class_name Player
extends CharacterBody2D

const BASE_MOVEMENT_SPEED: float = 100

const BASE_BULLET_DAMAGE: int = 1.0
signal died

@onready var player_input_synchronizer_component: PlayerInputSynchronizerComponent = $PlayerInputSynchronizerComponent
@onready var weapon_root: Node2D = $Visuals/WeaponRoot
@onready var fire_rate_timer: Timer = $FireRateTimer
@onready var health_component: HealthComponent = $HealthComponent
@onready var magic_component: MagicComponent = $MagicComponent

@onready var visuals: Node2D = $Visuals
@onready var weapon_animation_player: AnimationPlayer = $WeaponAnimationPlayer
@onready var barrel_position: Marker2D = $Visuals/WeaponRoot/WeaponAnimationRoot/BarrelPosition
@onready var display_name_label: Label = $DisplayNameLabel
@onready var activation_area_collision_shape: CollisionShape2D = %ActivationAreaCollisionShape
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var hurtbox_component: HurtboxComponent = $HurtboxComponent
@onready var weapon_stream_player: AudioStreamPlayer = $WeaponStreamPlayer
@onready var hit_stream_player: AudioStreamPlayer = $HitStreamPlayer
@onready var extra_attributes_component: ExtraAttributesComponent = $ExtraAttributesComponent

@onready var sprite_trail: Node = $Visuals/SpriteTrail
@onready var god_state_timer: Timer = %GodStateTimer

@onready var hitbox_component: HitboxComponent = $Visuals/HitboxComponent



#游戏进行时，玩家状态的定时器
@onready var freeze_state_timer: Timer = %FreezeStateTimer
@onready var freeze_buff: Node2D = %FreezeBuff





var bullet_scene: PackedScene = preload("res://entities/bullet/bullet.tscn")
var 冲击波_scene: PackedScene = preload("res://entities/bullet/冲击波.tscn")
var 下劈_scene: PackedScene = preload("res://entities/bullet/下劈.tscn")
var 翻江倒海_scene: PackedScene = preload("res://entities/skill/stable_once/翻江倒海.tscn")
var 金刚罩_scene: PackedScene = preload("res://entities/skill/stable_once_effect/金刚罩.tscn")
var 横斩_scene: PackedScene = preload("res://entities/bullet/横斩.tscn")
var 僧兵甲_scene: PackedScene = preload("res://entities/freind/僧兵甲.tscn")




var muzzle_flash_scene: PackedScene = preload("res://effect/muzzie_flash/muzzle_flash.tscn")
var ground_particles_scene: PackedScene = preload("res://effect/player_ground_particles/player_ground_particles.tscn")
var 春风化雨_scene = preload("res://entities/skill/stable_once_effect.tscn")



var boss_scene: PackedScene = preload("res://entities/boss/close/boss_close.tscn")


var is_dying: bool
var is_respawn: bool
var display_name: String

var is_skill: bool = false
var defence:bool = false


var player_type: String = "唐僧"


var base_fire_rate: float = .25
var base_health: float = 5.0
var base_magic: float = 5.0




var input_multiplayer_authority: int
var is_create_by_player = false


var is_freeze:bool
var god:String = ""
var god_timer = Time.get_ticks_msec()





func _ready():
	player_input_synchronizer_component.set_multiplayer_authority(input_multiplayer_authority)
	activation_area_collision_shape.disabled =\
		!player_input_synchronizer_component.is_multiplayer_authority()
		
	var is_single_player = multiplayer.multiplayer_peer is OfflineMultiplayerPeer
	var is_client_authority = player_input_synchronizer_component.is_multiplayer_authority()
	
	if player_type == "唐僧":
		base_fire_rate = 0.3

	if player_type == "孙悟空":
		weapon_root.visible = false
		base_fire_rate = 0.4

	if player_type == "猪八戒":
		weapon_root.visible = false
		base_fire_rate = 0.7

	if player_type == "沙悟净":
		weapon_root.visible = false
		base_fire_rate = 0.9
		
		
	
	if is_single_player || is_client_authority:
		display_name_label.visible = false
	else:
		display_name_label.text = display_name

	if is_multiplayer_authority():
		#if is_respawn:
			#health_component.current_health = 1
		health_component.died.connect(_on_died)
		hurtbox_component.hit_by_hitbox.connect(_on_hit_by_hitbox)
		
		freeze_state_timer.timeout.connect(_freeze_state_timer_timeout)
		god_state_timer.timeout.connect(_god_state_timer_timeout)

		
	
	EquipManager.current.connect(_on_pakage_change)
		
		
		
	



var move_velocity = null


func _process(delta: float) -> void:
	update_aim_position()
	
	var movement_vector := player_input_synchronizer_component.movement_vector
	if is_multiplayer_authority():
		if is_dying:
			global_position = Vector2.RIGHT * 1000
			return
		
		if !is_skill:
			var target_velocity = movement_vector * get_movement_speed()
			velocity = velocity.lerp(target_velocity, 1 - exp(-25 * delta))
			move_and_slide()
		else:
			if player_type == "孙悟空":
				if move_velocity == null:
					#if player_input_synchronizer_component.aim_vector.x < 0 :
						#move_velocity = Vector2.LEFT
					#else:
						#move_velocity = Vector2.RIGHT
					move_velocity = player_input_synchronizer_component.aim_vector
					sprite_trail.is_begin = false
				velocity = velocity.lerp(move_velocity * 500, 1 - exp(-25 * delta))
				move_and_slide()
				
			if player_type == "猪八戒":
				pass
		
		
		
		
		if player_input_synchronizer_component.is_attack_pressed == 1:
			try_fire()
		
		if player_input_synchronizer_component.is_attack_pressed == 2:
			try_skill1()
			
		
		if player_input_synchronizer_component.is_attack_pressed == 3:
			try_skill2()
		
		if god == "神":
			if Time.get_ticks_msec() - god_timer > 5000:
				god == ""
		
		
			
	if god == "神":
		sprite_trail.is_begin = true
		
		
	else:
		sprite_trail.is_begin = false

	
	
	if !is_skill:
	
		if is_equal_approx(movement_vector.length_squared(), 0):
			animation_player.play(god + player_type + "_idle")
		else:
			animation_player.play(god + player_type + "_run")
		
	#如果是单机，或者当前客户端，相机需要跟随玩家
	#相机要如何确定哪个是相机要跟随的，它要如何拿到玩家信息
	var is_single_player = multiplayer.multiplayer_peer is OfflineMultiplayerPeer
	var is_client_authority = player_input_synchronizer_component.is_multiplayer_authority()
	#如果是控制玩家节点，将其坐标发送给相机，让相机跟随
	if is_single_player || is_client_authority:
		GameEvents.camera_follow_player.emit(position)
	
	


func get_movement_speed() -> float:
	var movement_upgrade_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"movement_speed"
	)
	var speed_change := 1.0
	if is_freeze:
		speed_change -= 0.4
	
	if god == "神" :
		speed_change += 0.6
	
	var speed_modifier := (1 + (.15 * movement_upgrade_count))*speed_change
		
	return BASE_MOVEMENT_SPEED * speed_modifier




func get_fire_rate() -> float:
	var fire_rate_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"fire_rate"
	)
	if god == "神":
		fire_rate_count += 2
	
	return clampf(base_fire_rate * (1 - (.1 * fire_rate_count)),0.1,1)

func get_bullet_damage() -> float:
	var damage_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"damage"
	)
	
	#var damage_count = extra_attributes_component.attack_damage_current
	if god == "神":
		damage_count += 2
	
	return BASE_BULLET_DAMAGE + damage_count

func get_except_health() -> float:
	var health_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"提升血量"
	)
	#var damage_count = extra_attributes_component.attack_damage_current
	return base_health + health_count

func get_except_magic() -> float:
	var magic_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"提升蓝量"
	)
	#var damage_count = extra_attributes_component.attack_damage_current
	return base_magic + magic_count




func get_except_summon_strong() -> float:
	var summon_strong_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"提升召唤物强度"
	)
	#var damage_count = extra_attributes_component.attack_damage_current
	return summon_strong_count


func get_except_summon_sum() -> float:
	var summon_sum_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"提升召唤物数量"
	)
	#var damage_count = extra_attributes_component.attack_damage_current
	return 1 + summon_sum_count


func get_except_skill_sum(damgae:float = 1.0) -> float:
	var skill_sum_count := UpgradeManager.get_peer_upgrade_count(
		player_input_synchronizer_component.get_multiplayer_authority(),
		"提升技能伤害"
	)
	#var damage_count = extra_attributes_component.attack_damage_current
	return damgae + (skill_sum_count * 2)



@rpc("authority", "call_local")
func play_hit_effects():
	if player_input_synchronizer_component.is_multiplayer_authority():
		GameCamera.shake(1)
		hit_stream_player.play()

	
	var hit_particles: Node2D = ground_particles_scene.instantiate()
	var background_node: Node = Main.background_mask
	if !is_instance_valid(background_node):
		background_node = get_parent()

	background_node.add_child(hit_particles)
	hit_particles.global_position = global_position

	
	hurtbox_component.disable_collisions = true
	var tween := create_tween()
	tween.set_loops(10)
	tween.tween_property(visuals, "visible", false, .05)
	tween.tween_property(visuals, "visible", true, .05)
	
	tween.finished.connect(func ():
		hurtbox_component.disable_collisions = false
	)

func set_display_name(incoming_name: String):
	display_name = incoming_name


func set_player_type(player_type_name: String):
	player_type = player_type_name




func update_aim_position():
	var aim_vector = player_input_synchronizer_component.aim_vector
	var aim_position = weapon_root.global_position + aim_vector
	
	if !is_skill:
		visuals.scale = Vector2.ONE if aim_vector.x > 0 else Vector2(-1, 1)
		weapon_root.look_at(aim_position)


func try_fire():
	
	if player_type == "唐僧":
		
		if !fire_rate_timer.is_stopped():
			return

		var bullet = bullet_scene.instantiate() as Bullet
		bullet.damage = get_bullet_damage()
		bullet.global_position = barrel_position.global_position
		bullet.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()

		bullet.start(player_input_synchronizer_component.aim_vector)
		get_parent().add_child(bullet, true)
		
		fire_rate_timer.wait_time = get_fire_rate()
		
		fire_rate_timer.start()
		
		play_fire_effects.rpc()
	
	if player_type == "孙悟空":
		if !fire_rate_timer.is_stopped():
			return

		var bullet = 冲击波_scene.instantiate() as 冲击波
		bullet.damage = get_bullet_damage()
		bullet.global_position = global_position
		bullet.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()

		bullet.start(player_input_synchronizer_component.aim_vector)
		get_parent().add_child(bullet, true)
		
		fire_rate_timer.wait_time = get_fire_rate()
		
		fire_rate_timer.start()
		
		play_fire_effects.rpc()
	
	if player_type == "猪八戒":
		if !fire_rate_timer.is_stopped():
			return

		var bullet = 下劈_scene.instantiate() as 下劈
		bullet.damage = get_bullet_damage()
		bullet.global_position = global_position
		bullet.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()

		bullet.start(player_input_synchronizer_component.aim_vector)
		get_parent().add_child(bullet, true)
		
		fire_rate_timer.wait_time = get_fire_rate()
		
		fire_rate_timer.start()
		
		play_fire_effects.rpc()
	if player_type == "沙悟净":
		
		if !fire_rate_timer.is_stopped():
			return
		var bullet = 横斩_scene.instantiate() as 横斩
		bullet.damage = get_bullet_damage()
		bullet.global_position = global_position
		bullet.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()
		bullet.start(player_input_synchronizer_component.aim_vector)
		if god == "神":
			bullet.attribute = HitboxComponent.ATTRIBUTE_TYPE.治疗触发术
		
		get_parent().add_child(bullet, true)
		fire_rate_timer.wait_time = get_fire_rate()
		
		fire_rate_timer.start()

	
	

func try_skill1():
	
	if player_type == "唐僧" && !is_skill:
		play_spell.rpc()

	if player_type == "孙悟空" && !is_skill:

		play_spell.rpc()
		
	if player_type == "猪八戒" && !is_skill:
		play_spell.rpc()
	if player_type == "沙悟净" && !is_skill:
		if !defence:
			play_spell.rpc()

	
func try_skill2():
	
	if god != "神":
		#if god_state_timer.is_stopped() == true:
			var spended = magic_component.spend(1.0)
			if  spended:
				god = "神"
				god_timer = Time.get_ticks_msec()
				god_state_timer.start()





@rpc("authority", "call_local", "unreliable")
func play_fire_effects():
	
	if player_type == "唐僧":
		if weapon_animation_player.is_playing():
			weapon_animation_player.stop()
		weapon_animation_player.play("fire")
		var muzzle_flash: Node2D = muzzle_flash_scene.instantiate()
		muzzle_flash.global_position = barrel_position.global_position
		muzzle_flash.rotation = barrel_position.global_rotation
		get_parent().add_child(muzzle_flash)
		if player_input_synchronizer_component.is_multiplayer_authority():
			GameCamera.shake(1)
		weapon_stream_player.play()
	
	if player_type == "孙悟空":
		pass




@rpc("authority", "call_local", "unreliable")
func play_skill1_effects():
	
	if player_type == "唐僧":
		pass
	
	if player_type == "孙悟空":
		animation_player.play("孙悟空_skill")

var target_vector

@rpc("authority", "call_local", "reliable")
func play_spell():
	
	if player_type == "唐僧":
		var spended = magic_component.spend(1.0)
		if spended:
			is_skill = true
			animation_player.play(god+"唐僧_skill")
	
	if player_type == "孙悟空":
		var spended = magic_component.spend(1.0)
		if spended:
			is_skill = true
			
			hitbox_component.damage = get_except_skill_sum()
			hurtbox_component.disable_damage = true
			
			animation_player.play(god+"孙悟空_skill")
			if god == "神":
				sprite_trail.is_begin = true
				hitbox_component.damage = get_except_skill_sum(4.0)

			
		
	if player_type == "猪八戒":
		var spended = magic_component.spend(1.0)
		if spended:
			is_skill = true
			animation_player.play(god+"猪八戒_skill")
			target_vector = player_input_synchronizer_component.aim_vector
	if player_type == "沙悟净":
		var spended = magic_component.spend(1.0)
		if spended:		
			is_skill = true
			animation_player.play(god+"沙悟净_skill")
			defence = true

		
		
	
	
	
var  金刚罩_item:金刚罩 = null
	

func play_spell_end():
	
	is_skill = false
	move_velocity = null
	
	if player_type == "唐僧":
		if is_multiplayer_authority():
			var summon_sum = get_except_summon_sum()
			for i in summon_sum:
				var freind = 僧兵甲_scene.instantiate() as 僧兵甲
				freind.global_position = global_position + Vector2(i,i)
				freind.add_to_group("player")
				get_parent().add_child(freind, true)
		
	if player_type == "孙悟空":
		hurtbox_component.disable_damage = false
	
	if player_type == "猪八戒":
		var bullet = 翻江倒海_scene.instantiate() as 翻江倒海
		bullet.global_position = global_position
		bullet.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()
		bullet.damage = get_except_skill_sum(4.0)
		
		if god == "神":
			hitbox_component.damage = get_except_skill_sum(6.0)
		
		bullet.start(target_vector)
		get_parent().add_child(bullet, true)
		
	if player_type == "沙悟净":
			
		金刚罩_item = 金刚罩_scene.instantiate() as 金刚罩
		金刚罩_item.global_position = global_position
		金刚罩_item.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()
		金刚罩_item.start(self)

		get_parent().add_child(金刚罩_item, true)
		金刚罩_item.is_timeout.connect(_金刚罩timer_timeout)
	





func kill():
	if !is_multiplayer_authority():
		push_error("Cannot call kill on non-server client")
		return
	
	_kill.rpc()
	await get_tree().create_timer(.5).timeout

	died.emit()
	queue_free()


@rpc("authority", "call_local", "reliable")
func _kill():
	is_dying = true
	player_input_synchronizer_component.public_visibility = false


func _on_died():
	kill()

func _on_hit_by_hitbox(attribute:HitboxComponent.ATTRIBUTE_TYPE,is_damage:bool,damage:float):
	
	if attribute == HitboxComponent.ATTRIBUTE_TYPE.寒冰:
		is_freeze = true
		freeze_buff.visible = true
		if freeze_state_timer.is_stopped():
			freeze_state_timer.start()
		else:
			freeze_state_timer.stop()
			freeze_state_timer.start()
	
	if attribute == HitboxComponent.ATTRIBUTE_TYPE.治疗:
		var 春风化雨_item = 春风化雨_scene.instantiate() as StableOnceEffect
		春风化雨_item.global_position = global_position
		春风化雨_item.source_peer_id = player_input_synchronizer_component.get_multiplayer_authority()
		春风化雨_item.start(self)
		get_parent().add_child(春风化雨_item, true)
		
		


	
	
	if is_damage:
		play_hit_effects.rpc()

func _freeze_state_timer_timeout():
	is_freeze = false
	freeze_buff.visible = false
	

func _god_state_timer_timeout():
	god = ""
	

func _金刚罩timer_timeout():
	defence = false
	if 金刚罩_item:
		金刚罩_item.queue_free()
		金刚罩_item = null


func reset():
	
	health_component.reset_health(get_except_health())
	magic_component.reset_magic(get_except_magic())
	
	




#接受通知，根据背包变更玩家属性
func _on_pakage_growth(plus:EquipItem,item :EquipItem):
	
	#request_peer_ready.rpc_id(MultiplayerPeer.TARGET_PEER_SERVER)
	extra_attributes_component.growth(plus)
	extra_attributes_component.current(item)






@rpc("any_peer", "call_local", "reliable")
func package_current_ready(attack_damage:float,magic_damage:float,health:float,magic:float,attack_defult:float,magic_defult:float,
attack_damage_rate:float,magic_damage_rate:float,health_rate:float,magic_rate:float,attack_defult_rate:float,magic_defult_rate:float,
input_multiplayer_authority_context:int):
	
	if input_multiplayer_authority == input_multiplayer_authority_context:
		var item:=EquipItem.new()
		item.attack_damage = attack_damage
		item.magic_damage = attack_damage
		item.health = attack_damage
		item.magic = attack_damage
		item.attack_defult = attack_damage
		item.magic_defult = attack_damage
		
		item.attack_damage_rate = attack_damage_rate
		item.magic_damage_rate = attack_damage_rate
		item.health_rate = attack_damage_rate
		item.magic_rate = attack_damage_rate
		item.attack_defult_rate = attack_damage_rate
		item.magic_defult_rate = attack_damage_rate
		
		extra_attributes_component.current(item)



#背包变更
func _on_pakage_change(item:EquipItem):
	if player_input_synchronizer_component.is_multiplayer_authority():
		package_current_ready.rpc_id(MultiplayerPeer.TARGET_PEER_SERVER,
		item.attack_damage,item.magic_damage,item.health,item.magic,item.attack_defult,item.magic_defult,
		item.attack_damage_rate,item.magic_damage_rate,item.health_rate,item.magic_rate,item.attack_defult_rate,item.magic_defult_rate,
		 input_multiplayer_authority)

	
